package com.sunnybear.framework.tools;

import android.app.Dialog;
import android.content.Context;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.TextView;

import com.bigkoo.pickerview.builder.OptionsPickerBuilder;
import com.bigkoo.pickerview.builder.TimePickerBuilder;
import com.bigkoo.pickerview.listener.CustomListener;
import com.bigkoo.pickerview.listener.OnDismissListener;
import com.bigkoo.pickerview.listener.OnOptionsSelectListener;
import com.bigkoo.pickerview.listener.OnTimeSelectChangeListener;
import com.bigkoo.pickerview.listener.OnTimeSelectListener;
import com.bigkoo.pickerview.view.BasePickerView;
import com.bigkoo.pickerview.view.OptionsPickerView;
import com.bigkoo.pickerview.view.TimePickerView;
import com.caimuhao.rxpicker.utils.DensityUtil;
import com.sunnybear.framework.R;
import com.sunnybear.framework.ui.CustomTimePickerView;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * Picker工具
 *  2018/5/21.
 */
public final class PickerHelper {
    private static boolean isShowing;

    /**
     * 月份选择器
     *
     * @param context
     * @param onTimeSelectListener
     */
    public static void startMonthPicker(Context context, OnTimeSelectListener onTimeSelectListener) {
        if (isShowing) {
            return;
        }
        TimePickerView timePickerView = new TimePickerBuilder(context, onTimeSelectListener)
                .setContentTextSize((int) DensityUtil.px2sp(context, DensityUtil.sp2px(context, 20)))
                .setTextColorCenter(ResourcesUtils.getColor(context, R.color.black))
                .setTextColorOut(ResourcesUtils.getColor(context, R.color.color_b4b4b4))
                .setSubmitColor(ResourcesUtils.getColor(context, R.color.color_3296fa))
                .setCancelColor(ResourcesUtils.getColor(context, R.color.color_222222))
                .setTitleBgColor(ResourcesUtils.getColor(context, R.color.color_eeeeee))
                .setType(new boolean[]{true, true, false, false, false, false})
                .setLineSpacingMultiplier(2.0f)
                .setOutSideCancelable(false).isCyclic(true).isDialog(true).build();
        setBottomDialog(timePickerView);
        timePickerView.show();
        isShowing = true;
    }


    /**
     * 月份选择器 不包括未来时间
     *
     * @param context
     * @param onTimeSelectListener
     */
    public static void startNoFutureMonthPicker(Context context, OnTimeSelectListener onTimeSelectListener) {
        if (isShowing) {
            return;
        }
        Calendar start = Calendar.getInstance();
        Calendar end = Calendar.getInstance();
        start.set(1970, 0, 1);
        TimePickerView timePickerView = new TimePickerBuilder(context, onTimeSelectListener)
                .setContentTextSize((int) DensityUtil.px2sp(context, DensityUtil.sp2px(context, 20)))
                .setTextColorCenter(ResourcesUtils.getColor(context, R.color.black))
                .setTextColorOut(ResourcesUtils.getColor(context, R.color.color_b4b4b4))
                .setSubmitColor(ResourcesUtils.getColor(context, R.color.color_3296fa))
                .setCancelColor(ResourcesUtils.getColor(context, R.color.color_222222))
                .setTitleBgColor(ResourcesUtils.getColor(context, R.color.color_eeeeee))
                .setRangDate(start, end)
                .setDate(end)
                .setType(new boolean[]{true, true, false, false, false, false})
                .setLineSpacingMultiplier(2.0f)
                .setOutSideCancelable(false).isCyclic(false).isDialog(true).build();
        setBottomDialog(timePickerView);
        timePickerView.show();
        isShowing = true;
    }

    /**
     * 日期选择器
     *
     * @param context
     * @param onTimeSelectListener
     */
    public static void startNoFutureDatePicker(Context context, OnTimeSelectListener onTimeSelectListener) {
        if (isShowing) {
            return;
        }
        Calendar start = Calendar.getInstance();
        Calendar end = Calendar.getInstance();
        start.set(start.get(Calendar.YEAR) - 3, 0, 1);
        TimePickerView timePickerView = new TimePickerBuilder(context, onTimeSelectListener)
                .setContentTextSize((int) DensityUtil.px2sp(context, DensityUtil.sp2px(context, 20)))
                .setTextColorCenter(ResourcesUtils.getColor(context, R.color.black))
                .setTextColorOut(ResourcesUtils.getColor(context, R.color.color_b4b4b4))
                .setSubmitColor(ResourcesUtils.getColor(context, R.color.color_3296fa))
                .setCancelColor(ResourcesUtils.getColor(context, R.color.color_222222))
                .setTitleBgColor(ResourcesUtils.getColor(context, R.color.color_eeeeee))
                .setRangDate(start, end)
                .setDate(end)
                .setType(new boolean[]{true, true, true, false, false, false})
                .setLineSpacingMultiplier(2.0f)
                .setOutSideCancelable(false).isCyclic(true).isDialog(true).build();
        setBottomDialog(timePickerView);
        timePickerView.show();
        isShowing = true;
    }

    /**
     * 日期选择器
     *
     * @param context
     * @param onTimeSelectListener
     */
    public static void startNoFutureTimePicker(Context context, OnTimeSelectListener onTimeSelectListener) {
        if (isShowing) {
            return;
        }
        Calendar start = Calendar.getInstance();
        Calendar end = Calendar.getInstance();
        start.set(start.get(Calendar.YEAR) - 3, 0, 1);
        TimePickerView timePickerView = new TimePickerBuilder(context, onTimeSelectListener)
                .setContentTextSize((int) DensityUtil.px2sp(context, DensityUtil.sp2px(context, 20)))
                .setTextColorCenter(ResourcesUtils.getColor(context, R.color.black))
                .setTextColorOut(ResourcesUtils.getColor(context, R.color.color_b4b4b4))
                .setSubmitColor(ResourcesUtils.getColor(context, R.color.color_3296fa))
                .setCancelColor(ResourcesUtils.getColor(context, R.color.color_222222))
                .setTitleBgColor(ResourcesUtils.getColor(context, R.color.color_eeeeee))
                .setRangDate(start, end)
                .setDate(end)
                .setType(new boolean[]{true, true, true, true, true, true})
                .setLineSpacingMultiplier(2.0f)
                .setOutSideCancelable(false).isCyclic(false).isDialog(true).build();
        setBottomDialog(timePickerView);
        timePickerView.show();
        isShowing = true;
    }

    /**
     * 日期选择器
     *
     * @param context
     * @param onTimeSelectListener
     */
    public static void startDatePicker(Context context, OnTimeSelectListener onTimeSelectListener) {
        if (isShowing) {
            return;
        }
        TimePickerView timePickerView = new TimePickerBuilder(context, onTimeSelectListener)
                .setContentTextSize((int) DensityUtil.px2sp(context, DensityUtil.sp2px(context, 20)))
                .setTextColorCenter(ResourcesUtils.getColor(context, R.color.black))
                .setTextColorOut(ResourcesUtils.getColor(context, R.color.color_b4b4b4))
                .setSubmitColor(ResourcesUtils.getColor(context, R.color.color_3296fa))
                .setCancelColor(ResourcesUtils.getColor(context, R.color.color_222222))
                .setTitleBgColor(ResourcesUtils.getColor(context, R.color.color_eeeeee))
                .setType(new boolean[]{true, true, true, false, false, false})
                .setLineSpacingMultiplier(2.0f)
                .setOutSideCancelable(false).isCyclic(true).isDialog(true).build();
        setBottomDialog(timePickerView);
        timePickerView.show();
        isShowing = true;
    }

    /**
     * 停车时刻选择器
     *
     * @param context
     */
    public static void startParkTimePicker(Context context, String start, String end, final onParkTimeCallback onParkTimeCallback) {
        if (isShowing) {
            return;
        }
        final List<String> days = getFutureToWeek("MM月dd日 EEE");
        List<String> ds = getFutureToWeek("MM月dd日 EEE");
        ds.set(0, "今天");
        ds.set(1, "明天");
        ds.set(2, "后天");
        final List<String> hours = getHours(start, end);
        final List<String> minutes = getMinutes();
        final OptionsPickerView<String> optionsPickerView = new OptionsPickerBuilder(context, new OnOptionsSelectListener() {
            @Override
            public void onOptionsSelect(int options1, int options2, int options3, View v) {
                if (onParkTimeCallback != null) {
                    String day = days.get(options1);
                    String hour = hours.get(options2);
                    String minute = minutes.get(options3);
                    onParkTimeCallback.onParkingTime(day, hour, minute);
                }
            }
        }).setContentTextSize((int) DensityUtil.px2sp(context, DensityUtil.sp2px(context, 20)))
                .setTitleText("入场时间")
                .setTitleColor(ResourcesUtils.getColor(context, R.color.color_222222))
                .setTextColorCenter(ResourcesUtils.getColor(context, R.color.black))
                .setTextColorOut(ResourcesUtils.getColor(context, R.color.color_b4b4b4))
                .setSubmitColor(ResourcesUtils.getColor(context, R.color.color_3296fa))
                .setCancelColor(ResourcesUtils.getColor(context, R.color.color_222222))
                .setTitleBgColor(ResourcesUtils.getColor(context, R.color.color_fafafb))
                .setLabels("", "点", "分")
                .setCyclic(false, false, false)
                .setOutSideCancelable(false).isDialog(true)
                .setLineSpacingMultiplier(2.0f).build();
        optionsPickerView.setNPicker(ds, hours, minutes);
        setBottomDialog(optionsPickerView);
        optionsPickerView.show();
        isShowing = true;
    }

    /**
     * 停车时刻选择器 只能预约3小时内的
     *
     * @param context
     * @param start
     * @param end
     * @param onParkTimeCallback
     */
    public static void startParkTimePickerWithLimit(Context context, String start, String end, final onParkTimeCallback onParkTimeCallback) {
        if (isShowing) {
            return;
        }
        Date now = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) + 3);
        Date limit = calendar.getTime();

        final List<String> days = getFutureToWeek("MM月dd日 EEE");
        final List<List<String>> hours = new ArrayList<>();
        final List<List<List<String>>> minutes = new ArrayList<>();
        List<String> dayStrings = new ArrayList<>();
        dayStrings.add("今天");
        if (limit.getDate() != now.getDate()) {
            dayStrings.add("明天");

            int startHour = now.getHours();
            List<String> todayHours = new ArrayList<>();
            final List<List<String>> todayMins = new ArrayList<>();
            for (int i = startHour; i <= 24; i++) {
                todayHours.add(i + "");
                if (i == startHour) {
                    int startMin = now.getMinutes();
                    if (startMin % 5 != 0) {
                        startMin = 5 * (startMin / 5 + 1);
                    }
                    List<String> mins = getMinutesSpaceWith5(startMin, 60);
                    if (mins.size() <= 0) {
                        todayHours.remove(todayHours.size() - 1);
                    } else {
                        todayMins.add(mins);
                    }
                } else {
                    todayMins.add(getMinutesSpaceWith5(0, 60));
                }
            }
            hours.add(todayHours);
            minutes.add(todayMins);


            int endHour = limit.getHours();
            List<String> limitHours = new ArrayList<>();
            final List<List<String>> limitMins = new ArrayList<>();
            for (int i = 0; i <= endHour; i++) {
                limitHours.add(i + "");
                if (i == endHour) {
                    int endMin = now.getMinutes();
                    if (endMin % 5 != 0) {
                        endMin = 5 * (endMin / 5);
                    }
                    List<String> mins = getMinutesSpaceWith5(0, endMin);
                    if (mins.size() <= 0) {
                        limitHours.remove(todayHours.size() - 1);
                    } else {
                        limitMins.add(mins);
                    }
                } else {
                    limitMins.add(getMinutesSpaceWith5(0, 60));
                }
            }
            hours.add(limitHours);
            minutes.add(limitMins);
        } else {
            int startHour = now.getHours();
            int endHour = limit.getHours();
            List<String> todayHours = new ArrayList<>();
            final List<List<String>> todayMins = new ArrayList<>();
            for (int i = startHour; i <= endHour; i++) {
                todayHours.add(i + "");
                if (i == startHour) {
                    int startMin = now.getMinutes();
                    if (startMin % 5 != 0) {
                        startMin = 5 * (startMin / 5 + 1);
                    }
                    List<String> mins = getMinutesSpaceWith5(startMin, 60);
                    if (mins.size() <= 0) {
                        todayHours.remove(todayHours.size() - 1);
                    } else {
                        todayMins.add(mins);
                    }
                } else if (i == endHour) {
                    int endMin = now.getMinutes();
                    if (endMin % 5 != 0) {
                        endMin = 5 * (endMin / 5);
                    }
                    List<String> mins = getMinutesSpaceWith5(0, endMin);
                    if (mins.size() <= 0) {
                        todayHours.remove(todayHours.size() - 1);
                    } else {
                        todayMins.add(mins);
                    }
                } else {
                    todayMins.add(getMinutesSpaceWith5(0, 60));
                }
            }
            hours.add(todayHours);
            minutes.add(todayMins);
        }

        final OptionsPickerView<String> optionsPickerView = new OptionsPickerBuilder(context, new OnOptionsSelectListener() {
            @Override
            public void onOptionsSelect(int options1, int options2, int options3, View v) {
                if (onParkTimeCallback != null) {
                    String day = days.get(options1);
                    String hour = hours.get(options1).get(options2);
                    String minute = minutes.get(options1).get(options2).get(options3);
                    onParkTimeCallback.onParkingTime(day, hour, minute);
                }
            }
        }).setContentTextSize((int) DensityUtil.px2sp(context, DensityUtil.sp2px(context, 20)))
                .setTitleText("入场时间")
                .setTitleColor(ResourcesUtils.getColor(context, R.color.color_222222))
                .setTextColorCenter(ResourcesUtils.getColor(context, R.color.black))
                .setTextColorOut(ResourcesUtils.getColor(context, R.color.color_b4b4b4))
                .setSubmitColor(ResourcesUtils.getColor(context, R.color.color_3296fa))
                .setCancelColor(ResourcesUtils.getColor(context, R.color.color_222222))
                .setTitleBgColor(ResourcesUtils.getColor(context, R.color.color_fafafb))
                .setLabels("", "点", "分")
                .setCyclic(false, false, false)
                .setOutSideCancelable(false).isDialog(true)
                .setLineSpacingMultiplier(2.0f).build();
        optionsPickerView.setPicker(dayStrings, hours, minutes);
        setBottomDialog(optionsPickerView);
        optionsPickerView.show();
        isShowing = true;
    }

    /**
     * 获取未来一周的日期
     *
     * @param pattern
     * @return
     */
    private static List<String> getFutureToWeek(String pattern) {
        List<String> result = new ArrayList<>();
        for (int i = 0; i < 7; i++) {
            String day = DateUtils.getFutureDate(i, pattern);
//            if (!TextUtils.equals(day.split("月")[1], "10日") || !TextUtils.equals(day.split("月")[1], "20日")
//                    || !TextUtils.equals(day.split("月")[1], "30日"))
//                day = day.replace("0", "");
            result.add(day);
        }
        return result;
    }

    /**
     * 获取时
     *
     * @param start
     * @param end
     * @return
     */
    public static List<String> getHours(String start, String end) {
        List<String> hours = new ArrayList<>();
        if (TextUtils.isEmpty(start) || TextUtils.isEmpty(end)) {
            for (int i = 0; i < 24; i++) {
                hours.add(i + "");
            }
            return hours;
        }
        int startHour = getHour(start);
        int endHour = getHour(end);
        for (int i = startHour; i <= endHour; i++) {
            hours.add(i + "");
        }
        return hours;
    }

    private static int getHour(String hour) {
        String[] time = hour.split(":");
        if (TextUtils.isDigitsOnly(time[0]))
            return Integer.parseInt(time[0]);
        return -1;
    }


    /**
     * 三列 日期时间切换 时间选择器
     *
     * @param context              上下文
     * @param onTimeSelectListener 回调事件
     */
    public static void timePicker(final Context context, OnTimeSelectListener onTimeSelectListener) {
        if (isShowing) {
            return;
        }
        Calendar start = Calendar.getInstance();
        Calendar end = Calendar.getInstance();
        start.set(start.get(Calendar.YEAR) - 3, 0, 1);
        final CustomTimePickerView timePickerView = new CustomTimePickerView.TimePickerBuilder(context, onTimeSelectListener)
                .setContentTextSize((int) DensityUtil.px2sp(context, DensityUtil.sp2px(context, 20)))
                .setTextColorCenter(ResourcesUtils.getColor(context, R.color.color_3296fa))
                .setTextColorOut(ResourcesUtils.getColor(context, R.color.color_b4b4b4))
                .setSubmitColor(ResourcesUtils.getColor(context, R.color.color_3296fa))
                .setCancelColor(ResourcesUtils.getColor(context, R.color.color_222222))
                .setTitleBgColor(ResourcesUtils.getColor(context, R.color.color_eeeeee))
                .setRangDate(start, end)
                .setDate(end)
                .setType(new boolean[]{true, true, true, false, false, false})
                .setLineSpacingMultiplier(2.0f)
                .setOutSideCancelable(false).isCyclic(false).isDialog(true).build();
        timePickerView.getPickerOptions().layoutRes = R.layout.custom_pickerview_time;
        timePickerView.getPickerOptions().customListener = new CustomListener() {
            @Override
            public void customLayout(View v) {
                final TextView tvDate = v.findViewById(R.id.tv_date);
                final TextView tvTime = v.findViewById(R.id.tv_time);
                Date date = new Date();
                if (timePickerView.getPickerOptions().date != null) {
                    date = timePickerView.getPickerOptions().date.getTime();
                }
                tvDate.setText(DateUtils.format(date).substring(0, 10));
                tvTime.setText(DateUtils.format(date).substring(11, 19));
                TextView tvConfirm = v.findViewById(R.id.tv_confirm);
                View.OnClickListener click = new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        int i = v.getId();
                        v.setTag(System.currentTimeMillis());
                        if (i == R.id.tv_date) {
                            tvDate.setTextColor(ResourcesUtils.getColor(timePickerView.getPickerOptions().context, R.color.color_222222));
                            tvTime.setTextColor(ResourcesUtils.getColor(timePickerView.getPickerOptions().context, R.color.color_888888));
                            timePickerView.getPickerOptions().type = new boolean[]{true, true, true, false, false, false};
                            timePickerView.initWheelTime();
                        } else if (i == R.id.tv_time) {
                            tvDate.setTextColor(ResourcesUtils.getColor(timePickerView.getPickerOptions().context, R.color.color_888888));
                            tvTime.setTextColor(ResourcesUtils.getColor(timePickerView.getPickerOptions().context, R.color.color_222222));
                            timePickerView.getPickerOptions().type = new boolean[]{false, false, false, true, true, true};
                            timePickerView.initWheelTime();
                        } else if (i == R.id.tv_confirm) {
                            String time = tvDate.getText().toString() + " " + tvTime.getText().toString();
                            timePickerView.getPickerOptions().timeSelectListener.onTimeSelect(DateUtils.parse(time, "yyyy-MM-dd HH:mm:ss"), timePickerView.getClickView());
                            timePickerView.dismiss();
                        }
                    }
                };
                tvDate.setOnClickListener(click);
                tvTime.setOnClickListener(click);
                tvConfirm.setOnClickListener(click);
            }
        };
        timePickerView.getPickerOptions().timeSelectChangeListener = new OnTimeSelectChangeListener() {
            @Override
            public void onTimeSelectChanged(Date date) {
                TextView tvDate = (TextView) timePickerView.findViewById(R.id.tv_date);
                TextView tvTime = (TextView) timePickerView.findViewById(R.id.tv_time);
                Object dateTag = tvDate.getTag();
                Object timeTag = tvTime.getTag();
                if (timeTag == null) {
                    tvDate.setText(DateUtils.format(date).substring(0, 10));
                } else if (dateTag == null) {
                    tvTime.setText(DateUtils.format(date).substring(11, 19));
                } else {
                    long dateSelectTime = (long) dateTag;
                    long timeSelectTime = (long) timeTag;
                    if (dateSelectTime > timeSelectTime) {
                        tvDate.setText(DateUtils.format(date).substring(0, 10));
                    } else {
                        tvTime.setText(DateUtils.format(date).substring(11, 19));
                    }
                }
            }
        };
        timePickerView.initView(context);
        setBottomDialog(timePickerView);
        timePickerView.show();
        isShowing = true;
    }

    /**
     * 获取分
     *
     * @return
     */
    public static List<String> getMinutes() {
        List<String> minutes = new ArrayList<>();
        for (int i = 0; i < 60; i++) {
            minutes.add(i + "");
        }
        return minutes;
    }

    /**
     * 获取分
     *
     * @return
     */
    public static List<String> getMinutesSpaceWith5(int start, int end) {
        List<String> minutes = new ArrayList<>();
        for (int i = start; i <= (end == 60 ? 55 : end); i += 5) {
            minutes.add(i + "");
        }
        return minutes;
    }

    public interface onParkTimeCallback {

        void onParkingTime(String day, String hour, String minute);
    }

    public interface OnPlateSelectedListener {

        void onPlateSelected(String plate);
    }

    /**
     * 设置Picker底部弹出
     *
     * @param pickerView
     */
    private static void setBottomDialog(BasePickerView pickerView) {
        Dialog dialog = pickerView.getDialog();
        if (dialog != null) {
            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT,
                    Gravity.BOTTOM
            );
            params.leftMargin = 0;
            params.rightMargin = 0;
            pickerView.getDialogContainerLayout().setLayoutParams(params);
            Window dialogWindow = dialog.getWindow();
            if (dialogWindow != null) {
                dialogWindow.setWindowAnimations(com.bigkoo.pickerview.R.style.picker_view_slide_anim);//修改动画样式
                dialogWindow.setGravity(Gravity.BOTTOM);//改成Bottom,底部显示
            }
        }
        pickerView.setOnDismissListener(new OnDismissListener() {
            @Override
            public void onDismiss(Object o) {
                isShowing = false;
            }
        });
    }
}
